#ifndef LOCKER
#define LOCKER

#include <cstdio>
#include <iostream>
#include <exception>

#include <errno.h>
#include <pthread.h>

#include <semaphore.h>

/**
 * 2023-06-24
 * 编写互斥锁
 */
class MyMutex {
private:
    pthread_mutex_t mutex; // Linux提供的互斥锁

public:
    // 构造函数，初始化互斥锁
    MyMutex() {
        int res = pthread_mutex_init(&this->mutex, nullptr);

        if (res != 0) {
            std::cerr << "Fail to init Mutex, return non-zero-value: " << res << std::endl;
            perror("Mutex Init Fail"); // 互斥锁初始化失败
            throw std::exception();
        }
    }

    // 析构函数，销毁互斥锁
    ~MyMutex() {
        int res = pthread_mutex_destroy(&this->mutex);

        if (res != 0) {
            std::cerr << "Fail to Destroy Mutex, return non-zero value: " << res << std::endl;
            perror("Mutex Destroy Fail"); // 互斥锁销毁失败（析构函数不建议抛出异常）
        }
    }

    // 加锁
    bool lock() {
        int res = pthread_mutex_lock(&this->mutex); // 调用系统函数，给互斥锁上锁

        if (res == 0) {
            return true; // 成功上锁
        } else {
            std::cerr << "Mutex Lock return non-zero value: " << res << std::endl;
            perror("Mutex Lock Fail"); // 上锁失败
            return false;
        }
    }

    // 解锁
    bool unlock() {
        int res = pthread_mutex_unlock(&this->mutex);  // 调用系统函数，给互斥锁解锁

        if (res == 0) {
            return true; // 成功解锁
        } else {
            std::cerr << "Mutex Unlock return non-zero value: " << res << std::endl;
            perror("Mutex Unlock Fail"); // 解锁失败
            return false;
        }
    }

    // 获取互斥锁
    pthread_mutex_t* get_mutex() {
        return &this->mutex;
    }
};

/**
 * 2023-07-02
 * 编写一个条件变量类
 */
class MyCondition {
private:
    pthread_cond_t condition;
    
public:
    // 初始化条件变量
    MyCondition() {
        int res = pthread_cond_init(&this->condition, nullptr);

        if (res != 0) {
            std::cerr << "Condition Variable Init Fail, return ono-zero value: " << res << std::endl;
            perror("Condition Variable Init Fail"); // 条件变量初始化错误
            throw std::exception();
        }
    }

    // 销毁条件变量
    ~MyCondition() {
        int res = pthread_cond_destroy(&this->condition);

        if (res != 0) {
            std::cerr << "Condition Variable Destroy Fail, return non-zero value: " << res << std::endl;
            perror("Condition Variable Destroy Fail"); // 条件变量销毁错误（析构函数不建议抛出异常）
        }
    }

    // 实现Wait功能
    bool wait(pthread_mutex_t *mutex) {
        int res = pthread_cond_wait(&this->condition, mutex);

        if (res == 0) {
            return true; // 条件变量Wait成功
        } else {
            std::cerr << "Condition Variable Wait Fail, return non-zero value: " << res << std::endl;
            perror("Condition Variable Wait Fail");
            return false; // 条件变量wait失败
        }
    }

    // 实现Timed-Wait功能
    bool timed_wait(pthread_mutex_t *mutex, struct timespec t) {
        int res = pthread_cond_timedwait(&this->condition, mutex, &t);

        if (res == 0) {
            return true; // 条件变量Timed Wait成功
        } else {
            std::cerr << "Condition Variable Timed Wait Fail, return non-zero value: " << res << std::endl;
            perror("Condition Variable Timed Wait Fail");
            return false; // 条件变量Timed Wait失败
        }
    }

    // 实现Signal功能
    bool signal() {
        int res = pthread_cond_signal(&this->condition);

        if (res == 0) {
            return true; // 条件变量Signal成功
        } else {
            std::cerr << "Condition Variable Signal Fail, return non-zero value: " << res << std::endl;
            perror("Condition Variable Signal Fail");
            return false; // 条件变量Signal失败
        }
    }

    // 实现Broadcast功能
    bool broadcast() {
        int res = pthread_cond_broadcast(&this->condition);

        if (res == 0) {
            return true; // 条件变量Broadcast成功
        } else {
            std::cerr << "Condition Variable Broadcast Fail, return non-zero value: " << res << std::endl;
            perror("Condition Variable Broadcast Fail");
            return false; // 条件变量Broadcast失败
        }
    }
};

/**
 * 2023-07-03
 * 编写一个信号量类
 */
class MySemaphore {
private:
    sem_t semaphore;

public:
    // 初始化信号量
    MySemaphore() {
        int res = sem_init(&this->semaphore, 0, 0);

        if (res != 0) {
            std::cerr << "Semaphpre Init Fail, errno = " << errno << std::endl;
            perror("Semaphore Init Fail, "); // 处理信号量初始化失败
            throw std::exception();
        }
    }

    // 初始化信号量，根据指定的初始值
    explicit MySemaphore(int value) {
        int res = sem_init(&this->semaphore, 0, value);

        if (res != 0) {
            std::cerr << "Semaphpre Init Fail, errno = " << errno << std::endl;
            perror("Semaphore Init Fail, "); // 处理信号量初始化失败
            throw std::exception();
        }
    }

    // 销毁信号量
    ~MySemaphore() {
        int res = sem_destroy(&this->semaphore);

        if (res != 0) {
            std::cerr << "Semaphpre Destroy Fail, errno = " << errno << std::endl;
            perror("Semaphore Destroy Fail, "); // 处理信号量销毁失败
        }
    }

    // 实现Wait功能，等待信号量
    bool wait() {
        int res = sem_wait(&this->semaphore);

        if (res == 0) {
            return true;
        } else {
            std::cerr << "Semaphore Wait Fail, errno = " << errno << std::endl;
            perror("Semaphore Wait Fail, "); // 处理信号量Wait失败
            return false;
        }
    }

    // 实现Post功能，增加信号量
    bool post() {
        int res = sem_post(&this->semaphore);

        if (res == 0) {
            return true;
        } else {
            std::cerr << "Semaphore Post Fail, errno = " << errno << std::endl;
            perror("Semaphore Post Fail, "); // 处理信号量Post失败
            return false;
        }
    }
};

#endif